/*
 * Copyright 2007-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 * 
 * Project: gtinyurl
 */
package org.gnut.tinyurl.portlet.servlet;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.gnut.tinyurl.portlet.tag.ActionSupport;
import org.gnut.tinyurl.portlet.tag.UrlTagSupport;

/**
 * 
 * @author tungt
 * 
 */
public abstract class TinyUrl {
	private static Map cachedInstances = new HashMap();
	public static final String PORTLET_TAG_SUPPORT_CLASS = "org.gnut.tinyurl.portlet.tag.PortletTagSupport";
	public static final String SERVLET_TAG_SUPPORT_CLASS = "org.gnut.tinyurl.portlet.tag.ServletTagSupport";
	public static final String PORTLET_ACTION_SUPPORT_CLASS = "org.gnut.tinyurl.portlet.tag.PortletActionSupport";
	public static final String SERVLET_ACTION_SUPPORT_CLASS = "org.gnut.tinyurl.portlet.tag.ServletActionSupport";
	public static final String PORTLET_CONFIG_ATTRIBUTE = "javax.portlet.config";
	public static final String PORTLET_CONFIG_CLASS = "javax.portlet.PortletConfig";

	/**
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isPortletSupport(HttpServletRequest request) {
		Object object = request.getAttribute(PORTLET_CONFIG_ATTRIBUTE);
		System.out.println("javax.portlet.PortletConfig " + object);
		if (object != null) {
			try {
				Class clazz = Class.forName(PORTLET_CONFIG_CLASS);
				return clazz.isAssignableFrom(object.getClass());
			} catch (ClassNotFoundException e) {
			}
		}
		return false;
	}

	/**
	 * 
	 * @param request
	 * @param response
	 * @param urlTagSupport
	 * @return
	 * @throws Exception
	 */
	public static UrlTagSupport createUrlTagSupport(HttpServletRequest request,
			HttpServletResponse response, UrlTagSupport urlTagSupport)
			throws Exception {

		if (isPortletSupport(request)) {
			if (cachedInstances.containsKey(PORTLET_TAG_SUPPORT_CLASS)) {
				return (UrlTagSupport) cachedInstances
						.get(PORTLET_TAG_SUPPORT_CLASS);
			} else {
				Class clazz = Class.forName(PORTLET_TAG_SUPPORT_CLASS);
				UrlTagSupport support = (UrlTagSupport) clazz.newInstance();
				cachedInstances.put(PORTLET_TAG_SUPPORT_CLASS, support);
				return support;
			}
		} else {
			if (cachedInstances.containsKey(SERVLET_TAG_SUPPORT_CLASS)) {
				return (UrlTagSupport) cachedInstances
						.get(SERVLET_TAG_SUPPORT_CLASS);
			} else {
				Class clazz = Class.forName(SERVLET_TAG_SUPPORT_CLASS);
				UrlTagSupport support = (UrlTagSupport) clazz.newInstance();
				cachedInstances.put(SERVLET_TAG_SUPPORT_CLASS, support);
				return support;
			}
		}
	}

	/**
	 * 
	 * @param request
	 * @param isResource
	 * @param uri
	 * @return
	 */
	public static String createUrl(HttpServletRequest request,
			boolean isResource, String uri) {
		UrlTagSupport support;
		try {
			support = createUrlTagSupport(request, null, null);
			if (support != null)
				return support.createUrl(request, null, isResource, uri);
		} catch (Exception e) {
		}

		return null;
	}

	/**
	 * 
	 * @param request
	 * @param response
	 * @param actionSupport
	 * @return
	 * @throws Exception
	 */
	public static ActionSupport createActionSupport(HttpServletRequest request,
			HttpServletResponse response, ActionSupport actionSupport)
			throws Exception {

		if (isPortletSupport(request)) {
			if (cachedInstances.containsKey(PORTLET_ACTION_SUPPORT_CLASS)) {
				return (ActionSupport) cachedInstances
						.get(PORTLET_ACTION_SUPPORT_CLASS);
			} else {
				Class clazz = Class.forName(PORTLET_ACTION_SUPPORT_CLASS);
				ActionSupport support = (ActionSupport) clazz.newInstance();
				cachedInstances.put(PORTLET_ACTION_SUPPORT_CLASS, support);
				return support;
			}
		} else {
			if (cachedInstances.containsKey(SERVLET_ACTION_SUPPORT_CLASS)) {
				return (ActionSupport) cachedInstances
						.get(SERVLET_ACTION_SUPPORT_CLASS);
			} else {
				Class clazz = Class.forName(SERVLET_ACTION_SUPPORT_CLASS);
				ActionSupport support = (ActionSupport) clazz.newInstance();
				cachedInstances.put(SERVLET_ACTION_SUPPORT_CLASS, support);
				return support;
			}
		}
	}

	/**
	 * 
	 * @param request
	 * @param uri
	 * @param param
	 * @return
	 */
	public static String createActionUrl(HttpServletRequest request,
			String uri, Map param) {
		ActionSupport support;
		try {
			support = createActionSupport(request, null, null);
			if (support != null)
				return support.createAction(request, null, uri, param);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
}
